package com.evaluation.kexingcp.psycho.evaluation.sys.tenant

import arrow.core.Either
import arrow.core.raise.*
import arrow.core.right
import cn.hutool.core.util.RandomUtil
import com.alibaba.fastjson.JSON
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.toolkit.StringPool
import com.evaluation.kexingcp.admin.api.constant.TenantStateEnum
import com.evaluation.kexingcp.admin.api.entity.SysLog
import com.evaluation.kexingcp.admin.api.entity.SysTenant
import com.evaluation.kexingcp.admin.service.SysLogService
import com.evaluation.kexingcp.admin.service.SysTenantService
import com.evaluation.kexingcp.admin.service.SysUserService
import com.evaluation.kexingcp.common.core.constant.CacheConstants
import com.evaluation.kexingcp.common.core.constant.enums.LoginTypeEnum
import com.evaluation.kexingcp.common.data.resolver.ParamResolver
import com.evaluation.kexingcp.common.data.tenant.TenantBroker
import com.evaluation.kexingcp.common.data.tenant.TenantContextHolder
import com.evaluation.kexingcp.common.security.util.SecurityUtils
import com.evaluation.kexingcp.pay.entity.*
import com.evaluation.kexingcp.pay.service.*
import com.evaluation.kexingcp.psycho.evaluation.sys.entity.EvaluationTenantTypesEntity
import com.evaluation.kexingcp.psycho.evaluation.sys.service.EvaluationTenantTypesService
import com.evaluation.kexingcp.psycho.evaluation.sys.sms.SmsService
import com.evaluation.kexingcp.psycho.evaluation.sys.sms.WebSocketMsg
import com.evaluation.kexingcp.psycho.evaluation.sys.utils.plus
import com.evaluation.kexingcp.psycho.evaluation.sys.utils.runInTransaction
import com.ijpay.core.kit.AesUtil
import com.wechat.pay.java.core.RSAAutoCertificateConfig
import com.wechat.pay.java.core.http.Constant.*
import com.wechat.pay.java.service.payments.nativepay.NativePayService
import com.wechat.pay.java.service.payments.nativepay.model.Amount
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest
import jakarta.servlet.http.HttpServletRequest
import org.apache.commons.io.IOUtils
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.support.TransactionTemplate
import java.nio.charset.StandardCharsets
import java.time.Duration
import java.time.Instant
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread


sealed interface PesTenantError {
    val message: String
}

val privateKey = """
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCT8NKHzlNnp+KX
n9UMFogCiOirXx34TmRtPuAlQ7DjiohWkS72lLMGTG6CznEnbh5UtvKLmt1WdxP+
S8N5IZj9ZWo+Cahr/7U+g33tyaUxUw6dyWhr5BmcYph3e9c1/e+WnqsCWEcsDNI+
5E2boRK7R4atfT4E4SeVSqJxLeUNWYsiEhJKXKIic67JRNf5ZBXCmahh/3/iS/vT
4wLUox9Xpm/O/C4L7BNxlGDCodh/iFuvByoMwvZy2jZ9xhxtATy68IgaZ5MRsaDt
7JbaqqvMvJyrzryGKkLWAnKscHt4bhiAw0FU+vcARDILheEvbcmZNRg18h/48GWs
zunLUvApAgMBAAECggEAHrdGjunYyVHDKyYFTvAypwwT+tjR2Sc1lLUURshqJqQx
sH+OV6YCEZG29DO2rLAhXgdqDnBF+ljY7th+Kl0+bYYr69uHe3zo/aTBdaiDQt1y
0HHr21LNunmCHHS69zvVDdm9ucvoYw36bRJrxp9Hy1iLbuPtB4hT9pw7Y/Jad03K
U3PRp817yzvJ74H2QCq/4jw3+wxHThCmbQTzq4vwe2GXldnibFOIFRidg7/1dFbj
OH52CZZdMOdwP5Pg6WA1OkJaSdpuM0mTk7/wpqEKktaasiukXi71uxU+CyohPhcg
b5F8fHhCX/5aRSG8Mrzocyrf/nApLEenuvRIDEq/nQKBgQDEo9PhEvyVb/sRv8KB
IiSNtFIbbVrHIS7y4EOkqEhlynsx5HBpnLcKUqXrMK6gcF/qFqYdAT7yBFdgc1LN
tdVp3IMz16gGwmaT4M6egHLB9AdN0jb9NopQmIj9HjS6CMwdXP7o2gZzgtYH+Q6M
rjEHjgamk1PYPNir94QhWdSQKwKBgQDAmY7TjJ48qLIfyaz512+xp0pjLxMKGVUX
S0Tl3j8kpxL9zyAXLHmt/loBq4JZ0w9kV9W0o0eI84z+IgDCdBj6zUbYMsfTPkVV
iOvXrk2jv5ahopfxsqLJ69d4ODHG0Av35AIhF9k8icb/lNPBncHTJOABhINiPDMK
/cgaGnvC+wKBgF0OQmiS+aEmeyQtITjHFZFRskF0gK8XjwY1Bw3W7VvudFpqBqCU
HzLtZcNlKF6Yj2tSCI5VVpplX4wvRxI+aJ5OUnCoL8XzHWQB0QXFN4l9mC9Fuewe
cVoutTVDpCQdoaqLpb4/3ymu0ua3ACGnFWDD33XY5qbANLE80vSNdEA9AoGAE1fY
xlpbEhCHQzYID1eZuifpCqkRqnP83cgLdWKqyM2W1LLWsD0hQ15GP+CvyMGvzA4e
QnQbnR+Iy4UyulTapWW0dcYz131rjTmhJho1Zfq58CXaSMX+H3V2QHa0WRlP+meF
5zjz8maL++NAmTN04fXUIZLjdxxArBvs2uJKB70CgYBlpl8VDv+ZjlF/w3eX7uUk
p79c2ADD4z6+c9VsjFYNB8HU0eajZSMBIqSNmgZeyzwovsKbNGsa7EPPPpbcAMTp
syYokM5KyQPclI5m0IMPcQ3sx7aeuN8KYIK7jX6EYEf9xGezOUFgR6CmWIDQlm8e
818x2ReZSyz+kyeXp3Z2eA==
-----END PRIVATE KEY-----
""".trimIndent()
val merchantSerialNumber = "41930E38261C423A561F2123D887CBF8EA0BFD3F"
val apiV3Key = "qwertyuiopasdfghjklzxcvbnmxhxl17"

class PesTenantValidationError(override val message: String) : PesTenantError
class PesTenantRegisterError(override val message: String) : PesTenantError
class PesTenantPaymentError(override val message: String) : PesTenantError
class PesTenantPaymentCallbackError(override val message: String) : PesTenantError

data class TenantResp(val codeUrl: String, val tenantId: String, val orderId: String)

interface PesTenantService {
    fun createTenant(tenantRequest: TenantRequest, httpServletRequest: HttpServletRequest)
        : Either<PesTenantError, TenantResp>
    fun buySms(tenantRequest: SmsPaymentReq, httpServletRequest: HttpServletRequest)
            : Either<PesTenantError, TenantResp>
    fun buyVIP(tenantRequest: BugVIPReq, httpServletRequest: HttpServletRequest)
            : Either<PesTenantError, TenantResp>

    fun callback(request: HttpServletRequest): Either<PesTenantError, Unit>
    fun orderStatus(orderId: String): Either<PesTenantError, String>
    fun checkTenantStatus()
}

@Service
open class PesTenantsServiceImpl(
    private val sysTenantService: SysTenantService,
    private val redisTemplate: StringRedisTemplate,
    private val payGoodsService: PayGoodsService,
    private val payChannelService: PayChannelService,
    private val payGoodsOrderService: PayGoodsOrderService,
    private val transactionTemplate: TransactionTemplate,
    private val payTradeOrderService: PayTradeOrderService,
    private val payNotifyRecordService: PayNotifyRecordService,
    private val smsService: SmsService,
    private val evaluationTenantTypesService: EvaluationTenantTypesService,
    private val sysLogService: SysLogService,
    private val sysUserService: SysUserService
) : PesTenantService {
    private val log = LoggerFactory.getLogger(PesTenantsServiceImpl::class.java)

    @Value("\${spring.profiles.active}")
    private var profile: String = ""

    /**
     * 创建租户
     */
    @Transactional(rollbackFor = [Exception::class])
    override fun createTenant(tenantRequest: TenantRequest, httpServletRequest: HttpServletRequest)
        : Either<PesTenantError, TenantResp> = runInTransaction(transactionTemplate) {

            // 判断验证码是否正确
            // 参数校验过程
        val cacheKey = CacheConstants.DEFAULT_CODE_KEY +
                "${LoginTypeEnum.REG.type}${StringPool.AT}${tenantRequest.mobile}"
        val randomStr = RandomUtil.randomString(6).lowercase(Locale.getDefault())
        val cacheCode = redisTemplate.opsForValue().get(cacheKey)
        // TODO 验证手机号码

        httpServletRequest.setAttribute("mobile", tenantRequest.mobile)
        //ensureNotNull(cacheCode) { PesTenantValidationError("验证码已过期") }
        ensureNotNull(tenantRequest.validateCode) { PesTenantValidationError("验证码不能为空") }
        //ensure(cacheCode == tenantRequest.validateCode) { PesTenantValidationError("验证码错误") }
        val now = LocalDateTime.now()
        // 创建租户
        // 复制租户量表和用户字段显示
        val tenantType = evaluationTenantTypesService
            .getOne(QueryWrapper<EvaluationTenantTypesEntity>().eq("name", tenantRequest.orgType))
        val sysTenant = SysTenant().apply {
            name = tenantRequest.orgName
            code = randomStr
            tenantDomain = "$randomStr.sxkx.cn"
            status = "9"
            startTime = now
            endTime = now
            menuId = "1000,1100,1101,1102,1103,1104,1200,1201,1202,1203,1300,1301,1302,1303,1304,1305,1400,1401,1402" +
                    ",1403,1404,1600,1601,1602,1603,1604,1605,1500,1501,1508,1502,1504,1505,1506,1507,1503,9000,9005" +
                    ",9007,9070,9071,2300,9006,9050,9065,9051,9052,9053,9054,9055,9056,9057,9059,9060,9061,9062,9063" +
                    ",9064,2000"
            mobile = tenantRequest.mobile
            orgType = tenantRequest.orgType
            createBy = mobile
            createTime = now
            updateBy = mobile
            updateTime = now
            email = tenantRequest.email
            scales = tenantType.scales
            userFields = tenantType.userFileds
        }

        // 如果租户存在就更新吧
        sysTenantService.save(sysTenant)

        ensure(sysTenant.id != null && sysTenant.id > 0) {
            log.error("租户创建失败 {}", sysTenant)
            PesTenantRegisterError("租户创建失败")
        }

        val isBuyTenant = ParamResolver.getLong("IS_BUY_TENANT", 1);

        if (isBuyTenant?.toInt() == 0) {
            paySuccessCallback(sysTenant)
            TenantResp("", sysTenant.id.toString(), "").right()
        } else {
            // 找到商品
            val goods = payGoodsService.getOne(QueryWrapper<PayGoodsEntity>().eq("goods_name", "年会员"))
            ensureNotNull(goods) { PesTenantPaymentError("找不到商品") }


            getWeChatPay(1, goods, httpServletRequest, sysTenant, null)
        }
    }

    override fun buySms(
        tenantRequest: SmsPaymentReq,
        httpServletRequest: HttpServletRequest,
    ): Either<PesTenantError, TenantResp> = runInTransaction(transactionTemplate) {
        // 找到商品
        val goods = payGoodsService.getOne(QueryWrapper<PayGoodsEntity>().eq("goods_name", "短信发送1000条"))
        ensureNotNull(goods) { PesTenantPaymentError("找不到商品") }

        val sysTenant = sysTenantService.getOne(QueryWrapper<SysTenant>().eq("id", TenantContextHolder.getTenantId()))
        getWeChatPay(tenantRequest.num!!, goods, httpServletRequest, sysTenant, null)
    }

    override fun buyVIP(
        tenantRequest: BugVIPReq,
        httpServletRequest: HttpServletRequest,
    ): Either<PesTenantError, TenantResp> = runInTransaction(transactionTemplate) {
        val goods = payGoodsService.getById(tenantRequest.goodsId)
        ensureNotNull(goods) { PesTenantPaymentError("找不到商品") }

        val sysTenant = sysTenantService.getOne(QueryWrapper<SysTenant>().eq("id", tenantRequest.tenantId))
        val userID = TenantBroker.applyAs(sysTenant.id) { sysUserService.getUserVoByUsername(tenantRequest.username) }

        getWeChatPay(1, goods, httpServletRequest, sysTenant, userID.userId)
    }



    private fun getWeChatPay(num: Int = 1, goods : PayGoodsEntity, httpServletRequest: HttpServletRequest, sysTenant: SysTenant, userID: Long?) = either {
        // 读取商户配置
        val channel = payChannelService.getOne(QueryWrapper<PayChannel>().eq("channel_id", "WEIXIN_NATIVE"))
        ensureNotNull(channel) { log.error("读取支付配置失败");PesTenantPaymentError("支付错误") }

        val notifyUrl  = if (profile == "v2") {
            "https://apis.sxkx.cn/admin/tenants/wx/paymentCallback"
        } else {
            "https://api.sxkx.cn/admin/tenants/wx/paymentCallback"
        }

        // 创建订单
        val orderAmount = (goods.goodsPrice.times(num.toBigDecimal()));
        val goodsOrder = PayGoodsOrder().also {
            it.goodsId = goods.id.toString()
            it.goodsName = goods.goodsName
            it.amount = orderAmount.toString()
            it.status = "0"
            it.createTime = LocalDateTime.now()
            it.userId = if (SecurityUtils.getUser() != null) SecurityUtils.getUser().id.toString() else {
                userID?.toString() ?: sysTenant.id.toString()
            }
            it.goodsNum = num
            it.tenantId = sysTenant.id
        }
        payGoodsOrderService.save(goodsOrder)

        // 创建支付订单
        val payTradeOrder = PayTradeOrder().also {
            it.amount = goods.goodsPrice.toString()
            it.orderId = goodsOrder.goodsOrderId
            it.currency = "CNY"
            it.status = "0"
            it.clientIp = httpServletRequest.remoteAddr
            it.device = "PC"
            it.body = goods.goodsName
            it.channelMchId = channel.channelMchId
            it.channelId = channel.channelId
            it.createTime = LocalDateTime.now()
            it.tenantId = sysTenant.id
        }
        payTradeOrderService.save(payTradeOrder)

        val config = getRSAAutoCertificateConfig(channel)
        // 构建service
        val service: NativePayService = NativePayService.Builder().config(config).build()
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        val request = PrepayRequest().also {
            val amount = Amount()
            amount.total = orderAmount.times(100.toBigDecimal()).toInt()
            it.amount = amount
            it.appid = channel.appId
            it.mchid = channel.mchId
            it.description = goods.goodsName
            it.notifyUrl = notifyUrl
            it.outTradeNo = goodsOrder.goodsOrderId.toString()
        }

        // 调用下单方法，得到应答
        val response = catch({ service.prepay(request) }) {
                e -> log.error("支付失败: {}", e.message, e)
            raise(PesTenantPaymentError("支付错误"))
        }

        // 使用微信扫描 code_url 对应的二维码，即可体验Native支付
        TenantResp(response.codeUrl, sysTenant.id.toString(), goodsOrder.goodsOrderId.toString())
    }

    private fun getRSAAutoCertificateConfig(channel: PayChannel) : RSAAutoCertificateConfig {


        // 使用自动更新平台证书的RSA配置
        // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
        return RSAAutoCertificateConfig.Builder()
            .merchantId(channel.mchId)
            .privateKey(privateKey)
            .merchantSerialNumber(merchantSerialNumber)
            .apiV3Key(apiV3Key)
            .build()
    }

    private fun parseWechatData(request: HttpServletRequest, body: String) = either {
        val channel = payChannelService.getOne(QueryWrapper<PayChannel>().eq("channel_id", "WEIXIN_NATIVE"))
        ensureNotNull(channel) { log.error("读取支付配置失败");PesTenantPaymentError("支付错误") }
        val config = getRSAAutoCertificateConfig(channel)
        val verifier = config.createVerifier()
        val timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP)
        val responseTime = Instant.ofEpochSecond(timestamp.toLong())
        if (Duration.between(responseTime, Instant.now()).abs().toMinutes() >= 5) {
            log.error("Validate http response,timestamp$timestamp of " +
                    "httpResponse is expires, request-id[${request.getHeader(REQUEST_ID)}]")
            raise(PesTenantPaymentCallbackError("回调发送延迟超过5分钟"))
        }

        val message = "$timestamp\n${request.getHeader(WECHAT_PAY_NONCE)}\n$body\n"
        log.info("Message for verifying signatures is[{}]", message)
        val serialNumber = request.getHeader(WECHAT_PAY_SERIAL);
        log.info("SerialNumber for verifying signatures is[{}]", serialNumber);
        val signature = request.getHeader(WECHAT_PAY_SIGNATURE);
        log.info("Signature for verifying signatures is[{}]", signature);
        if (!verifier.verify(serialNumber, message, signature)) {
            log.error("data verify error")
            raise(PesTenantPaymentCallbackError("数据验证失败"))
        }

        val root = JSON.parseObject(body)
        val associateData = root.getJSONObject("resource").getString("associated_data")
        val nonce = root.getJSONObject("resource").getString("nonce")
        val ciphertext = root.getJSONObject("resource").getString("ciphertext")
        // 2 解析数据
        val aesUtil = AesUtil(apiV3Key.toByteArray())
        val data = aesUtil.decryptToString(associateData.toByteArray(StandardCharsets.UTF_8),
            nonce.toByteArray(StandardCharsets.UTF_8), ciphertext);
        log.info("解析回调数据 {}", data)

        data
    }

    private fun paySuccessCallback(sysTenant: SysTenant) {
        TenantContextHolder.setUserName(sysTenant.createBy)

        thread(start = true, isDaemon = true) {
            log.info("开始发送短信.....")
            smsService.sendRegisterSuccessSms(sysTenant.createBy, sysTenant.name)
        }

        thread(start = true, isDaemon = true) {
            log.info("开始发送邮件.....")
            smsService.sendRegisterEmail(sysTenant.email,
                sysTenant.name, sysTenant.createBy, sysTenant.tenantDomain, null)
        }

        thread(start = true, isDaemon = true) {
            log.info("取消冻结，给用户增加权限.....")
            sysTenant.status = "0"
            sysTenant.endTime = LocalDateTime.now().plus(ParamResolver.getLong("DEFAULT_FREE_DAYS", 1), TimeUnit.DAYS)
            sysTenantService.updateTenant(sysTenant)
            sysTenantService.saveTenant(sysTenant)
        }
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun callback(request: HttpServletRequest): Either<PesTenantError, Unit>
        = runInTransaction(transactionTemplate) {
        val body = IOUtils.toString(request.reader)
        // 1 验证请求真的来自微信
        log.info("微信通知发过来")
        val data = parseWechatData(request, body).bind()
        ensureNotNull(data) { log.error("微信数据解析异常： {}", data); PesTenantPaymentCallbackError("微信数据解析异常!") }
        // 3 处理业务逻辑
        val root = JSON.parseObject(data)
        val orderId = root.getString("out_trade_no")
        log.info("out_trade_no = ${orderId.toLong()}")

        val queryWrapper = QueryWrapper<PayGoodsOrder>()
        queryWrapper.eq("goods_order_id", orderId)
        queryWrapper.last("for update")
        val order = payGoodsOrderService.getOne(queryWrapper)
        ensureNotNull(order) { log.error("订单不存在 {}", orderId);PesTenantPaymentCallbackError("订单不存在!") }

        val tradeOrder = payTradeOrderService
            .getOne(QueryWrapper<PayTradeOrder>().eq("order_id", orderId).last("for update"))
        ensureNotNull(tradeOrder) { log.error("交易订单不存在 {}", orderId);PesTenantPaymentCallbackError("交易订单不存在!") }
        tradeOrder.notifyCount += 1
        tradeOrder.lastNotifyTime = LocalDateTime.now()
        val sysTenant = sysTenantService.getById(order.tenantId)
        ensureNotNull(sysTenant) { log.error("租户不存在 {}", order.tenantId);PesTenantPaymentCallbackError("购买的租户不存在!") }

        TenantBroker.runAs(sysTenant.id) {
            // 记录回调记录
            val payNotifyRecord = PayNotifyRecord().also {
                it.request = body
                it.response = ""
                it.orderNo = orderId
                it.createTime = LocalDateTime.now()
                it.updateTime = LocalDateTime.now()
            }
            payNotifyRecordService.save(payNotifyRecord)

            if (order.status.toInt() > 0) {
                log.info("订单已支付")
                raise(PesTenantPaymentCallbackError("订单已支付"))
            }

            if (root.getString("trade_state") == "SUCCESS" && order.status == "0") {
                log.info("微信支付成功 {}", data)
                // 订单支付成功
                order.status = "1"
                order.updateTime = LocalDateTime.now()
                order.payOrderId = root.getString("transaction_id")
                payGoodsOrderService.updateById(order)

                // 订单支付成功
                tradeOrder.paySuccTime = LocalDateTime.now()
                tradeOrder.updateTime = LocalDateTime.now()
                tradeOrder.status = "3"
                payTradeOrderService.updateById(tradeOrder)

                val goods = payGoodsService.getOne(QueryWrapper<PayGoodsEntity>().eq("goods_name", order.goodsName))
                if (goods != null) {
                    log.info("支付成功商品名称： {}", goods.goodsName)

                    when (goods.goodsName) {
                        "短信发送1000条" -> {
                            sysTenant.smsNum += (order.goodsNum * 1000)
                            sysTenantService.updateById(sysTenant)

                            smsService.sendWebSocketMsg(listOf(order.userId.toLong()), WebSocketMsg("payment", "支付成功!"))
                        }
                        "1年套餐" -> {
                            val days = ChronoUnit.DAYS.between(LocalDateTime.now(), sysTenant.endTime)
                            if (days > 0) {
                                sysTenant.endTime = sysTenant.endTime.plusYears(1)
                            } else {
                                sysTenant.endTime = LocalDateTime.now().plusYears(1)
                            }

                            sysTenantService.updateById(sysTenant)
                        }
                        "2年套餐" -> {
                            val days = ChronoUnit.DAYS.between(LocalDateTime.now(), sysTenant.endTime)
                            if (days > 0) {
                                sysTenant.endTime = sysTenant.endTime.plusYears(2)
                            } else {
                                sysTenant.endTime = LocalDateTime.now().plusYears(1)
                            }
                            sysTenantService.updateById(sysTenant)
                        }
                        "3年套餐" -> {
                            val days = ChronoUnit.DAYS.between(LocalDateTime.now(), sysTenant.endTime)
                            if (days > 0) {
                                sysTenant.endTime = sysTenant.endTime.plusYears(3)
                            } else {
                                sysTenant.endTime = LocalDateTime.now().plusYears(1)
                            }

                            sysTenantService.updateById(sysTenant)
                        }
                        else -> {
                           raise(PesTenantPaymentCallbackError("商品不存在"))
                        }
                    }
                }

                // 业务处理完成
                order.status = "2"
                order.updateTime = LocalDateTime.now()
                payGoodsOrderService.updateById(order)
            }

            if (root.getString("trade_state") != "SUCCESS"){
                log.error("微信支付失败 {}", data)
                order.status = "-1"
                payGoodsOrderService.updateById(order)

                smsService.sendWebSocketMsg(listOf(order.userId.toLong()), WebSocketMsg("payment", "支付失败!"))
            }
        }

        Unit.right()
    }

    override fun orderStatus(orderId: String): Either<PesTenantError, String> = either {
        val order = payGoodsOrderService.getOne(QueryWrapper<PayGoodsOrder>().eq("goods_order_id", orderId))
        ensureNotNull(order) { raise(PesTenantPaymentError("订单不存在")) }

        order.status
    }

    //@Scheduled(fixedRate = 1000 * 60 * 60 * 24) // 一天执行一次
    @Scheduled(fixedRate = 1000 * 30) // 一天执行一次
    override fun checkTenantStatus() {
        log.info("处理租户状态...")

        // 1 找出所有租户
        val tenants = sysTenantService.list()
        // 2 切换租户上下文
        for (tenant in tenants) {
            if (tenant.status == TenantStateEnum.NORMAL.code)
            {
                TenantBroker.applyAs(tenant.id) {
                    val sysLog = sysLogService.getOne(QueryWrapper<SysLog>().eq("title", "登录成功").orderByDesc("create_time"), false)
                    // 如果sysLog的create_time距离现在的时间超过3个月，则关闭租户
                    if (sysLog != null && sysLog.createTime.plusMonths(3).isBefore(LocalDateTime.now())) {
                        // 关闭租户
                        tenant.status = "9" //冻结
                        sysTenantService.updateById(tenant)
                    }
                }
            }
        }
    }
}